package app.pool.client;

import app.pool.utils.FileContentUtils;
import app.pool.utils.JSONUtils;
import app.pool.utils.MD5Utils;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.apache.commons.io.FileUtils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class App {

    public static void main(String[] args) {
        if(args.length < 2){
            System.out.println("请输入服务器地址，要上传的文件路径");
            System.exit(1);
        }
        
        String server = args[0];
        String filepath = args[1];

        if(server == null
                || server.isEmpty()){
            System.out.println("服务器地址不存在");
        }

        File jarfile = new File(filepath);
        if (!jarfile.exists()) {
            System.out.println("文件" + jarfile + "不存在");
            System.exit(1);
        }

        try {
            upload(server, jarfile);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(2);
        }
    }

    private static void upload(String server, File jarfile) throws UnirestException, IOException {
        byte[] filecontent = FileUtils.readFileToByteArray(jarfile);
        List<EntryInfo> entryInfosSelf = EntryInfo.fromZipfile(jarfile, filecontent);
        List<EntryInfo> entryInfosDiff = diffWithServer(server, entryInfosSelf);
        byte[] smallNewFile = createSmallFile(jarfile, filecontent, entryInfosDiff);
        uploadFile(server, jarfile, smallNewFile, entryInfosDiff);
    }

    private static void uploadFile(String server, File originalFile, byte[] smallFile, List<EntryInfo> entryInfos) throws UnirestException, IOException {

        String md5 = MD5Utils.getMD5(FileUtils.readFileToByteArray(originalFile));
        System.out.println("文件" + originalFile.getAbsolutePath() + "的MD5为" + md5);

        System.out.println("原文件大小" + originalFile.length() + ", 实际上传文件大小" + smallFile.length + ", 原文件大小 / 实际上传文件大小  = " + (originalFile.length() * 1.0 / smallFile.length));

        HttpResponse<String> res = Unirest.post(server + "/files/upload")
                .field("file", new ByteArrayInputStream(smallFile), originalFile.getName())
                .field("md5", md5)
                .field("entryInfos", JSONUtils.toJSON(entryInfos))
                .asString();
        if (res.getStatus() != 200) {
            System.out.println(res.getStatus() + "," + res.getBody());
            throw new RuntimeException("出错了");
        }
    }

    private static byte[] createSmallFile(File file, byte[] filecontent, List<EntryInfo> entryInfos) {
        for (EntryInfo entryInfo : entryInfos) {
            System.out.println("服务器中有Entry的缓存数据, EntryName=" + entryInfo.getName());
        }
        FileContentUtils.FileParts fileParts = EntryInfo.toFileParts(entryInfos);
        return FileContentUtils.deleteFileContent(filecontent, fileParts);
    }

    private static List<EntryInfo> diffWithServer(String server, List<EntryInfo> entryInfos) throws UnirestException {
        HttpResponse<String> res = Unirest.post(server + "/files/diff")
                .header("Content-Type", "application/json")
                .body(JSONUtils.toJSON(entryInfos)).asString();
        if (res.getStatus() != 200) {
            System.out.println(res.getStatus() + "," + res.getBody());
            throw new RuntimeException("出错了");
        }
        String body = res.getBody();
        return JSONUtils.toList(body, EntryInfo.class);
    }

}

